ioemu: Expandable storage backends should defeat block-device range checks.
authorKeir Fraser <keir.fraser@citrix.com>
Wed, 27 Feb 2008 13:21:36 +0000 (13:21 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Wed, 27 Feb 2008 13:21:36 +0000 (13:21 +0000)
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
tools/ioemu/block-qcow.c
tools/ioemu/block-qcow2.c
tools/ioemu/block-raw.c
tools/ioemu/block-vmdk.c
tools/ioemu/block.c
tools/ioemu/block_int.h
tools/ioemu/vl.h

index d5333b379d7327b1bd414d2ed6ffcc652305a792..458450dc08fa55328245a6d3af74547662044d23 100644 (file)
@@ -95,7 +95,7 @@ static int qcow_open(BlockDriverState *bs, const char *filename, int flags)
     int len, i, shift, ret;
     QCowHeader header;
 
-    ret = bdrv_file_open(&s->hd, filename, flags);
+    ret = bdrv_file_open(&s->hd, filename, flags | BDRV_O_EXTENDABLE);
     if (ret < 0)
         return ret;
     if (bdrv_pread(s->hd, 0, &header, sizeof(header)) != sizeof(header))
index a876ea2e2dc2a759eca574d4ea55200308c4fe69..a5f825538957e5841ca02ed9d48fb89259229a4c 100644 (file)
@@ -191,7 +191,7 @@ static int qcow_open(BlockDriverState *bs, const char *filename, int flags)
     int len, i, shift, ret;
     QCowHeader header;
 
-    ret = bdrv_file_open(&s->hd, filename, flags);
+    ret = bdrv_file_open(&s->hd, filename, flags | BDRV_O_EXTENDABLE);
     if (ret < 0)
         return ret;
     if (bdrv_pread(s->hd, 0, &header, sizeof(header)) != sizeof(header))
index 182d2ec55e07457361f1192e2cd835cbab751f68..f0ad65e0a70720dc466c2f0c5ab0ea53b6dedd76 100644 (file)
@@ -1489,5 +1489,7 @@ BlockDriver bdrv_host_device = {
     .bdrv_pread = raw_pread,
     .bdrv_pwrite = raw_pwrite,
     .bdrv_getlength = raw_getlength,
+
+    .bdrv_flags = BLOCK_DRIVER_FLAG_EXTENDABLE
 };
 #endif /* _WIN32 */
index 28df8ae466400c4cf0e6b6f0bf25e3a8cdd0266b..0558977abcb8ede5c80e8c5d82b32542222b5b99 100644 (file)
@@ -352,7 +352,7 @@ static int vmdk_open(BlockDriverState *bs, const char *filename, int flags)
     uint32_t magic;
     int l1_size, i, ret;
 
-    ret = bdrv_file_open(&s->hd, filename, flags);
+    ret = bdrv_file_open(&s->hd, filename, flags | BDRV_O_EXTENDABLE);
     if (ret < 0)
         return ret;
     if (bdrv_pread(s->hd, 0, &magic, sizeof(magic)) != sizeof(magic))
index 683dd2e0916d64aa0c283aba3377335397b58735..c9e27d1191a91d061d118acdefcb3b189a1c5bd7 100644 (file)
@@ -123,20 +123,23 @@ void path_combine(char *dest, int dest_size,
 static int bdrv_rw_badreq_sectors(BlockDriverState *bs,
                                int64_t sector_num, int nb_sectors)
 {
-    return
+    return (
        nb_sectors < 0 ||
        nb_sectors > bs->total_sectors ||
-       sector_num > bs->total_sectors - nb_sectors;
+       sector_num > bs->total_sectors - nb_sectors
+       ) && !bs->extendable;
 }
 
 static int bdrv_rw_badreq_bytes(BlockDriverState *bs,
                                  int64_t offset, int count)
 {
     int64_t size = bs->total_sectors << SECTOR_BITS;
-    return
+    return (
        count < 0 ||
        count > size ||
-       offset > size - count;
+       offset > size - count
+       ) && !bs->extendable;
+    
 }
 
 void bdrv_register(BlockDriver *bdrv)
@@ -347,6 +350,12 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
     bs->is_temporary = 0;
     bs->encrypted = 0;
 
+    if (flags & BDRV_O_EXTENDABLE) {
+       if (!(drv->bdrv_flags & BLOCK_DRIVER_FLAG_EXTENDABLE))
+           return -ENOSYS;
+       bs->extendable = 1;
+    }
+
     if (flags & BDRV_O_SNAPSHOT) {
         BlockDriverState *bs1;
         int64_t total_size;
index 25f6717b5c53a882413fe6c1ca79b0eefd0ebef2..fba27c2c3561b5cb838ca28d08a8ade2101166e5 100644 (file)
@@ -24,6 +24,8 @@
 #ifndef BLOCK_INT_H
 #define BLOCK_INT_H
 
+#define BLOCK_DRIVER_FLAG_EXTENDABLE  0x0001u
+
 struct BlockDriver {
     const char *format_name;
     int instance_size;
@@ -76,6 +78,7 @@ struct BlockDriver {
     int (*bdrv_eject)(BlockDriverState *bs, int eject_flag);
     int (*bdrv_set_locked)(BlockDriverState *bs, int locked);
     
+    unsigned bdrv_flags;
     BlockDriverAIOCB *free_aiocb;
     struct BlockDriver *next;
 };
@@ -87,6 +90,7 @@ struct BlockDriverState {
     int removable; /* if true, the media can be removed */
     int locked;    /* if true, the media cannot temporarily be ejected */
     int encrypted; /* if true, the media is encrypted */
+    int extendable;/* if true, we may write out of original range */
     /* event callback when inserting/removing */
     void (*change_cb)(void *opaque);
     void *change_opaque;
index c84a60920d7301722d65562df57e3d0a2982e2ec..0c5a9da97f1705f38e0c0f23b1d1e7b8902e939b 100644 (file)
@@ -614,6 +614,8 @@ typedef struct QEMUSnapshotInfo {
                                      use a disk image format on top of
                                      it (default for
                                      bdrv_file_open()) */
+#define BDRV_O_EXTENDABLE  0x0080 /* allow writes out of original size range;
+                                    only effective for some drivers */
 
 void bdrv_init(void);
 BlockDriver *bdrv_find_format(const char *format_name);